<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <canvas id="myCanvas" width="1080" height="630" style="border: 1px solid;"></canvas>
</body>

</html>
<script>

    const ctx = myCanvas.getContext('2d');

    let p1 = [300, 250];
    let p2 = [500, 250];


    function getVctLen([x, y]) {
        return Math.sqrt(x * x + y * y);
    };

    /**
     * 向量逆时针旋转angle角度后得到新的向量
     */
    getRotateVct = function (vct, angle) {
        let rad = angle * Math.PI / 180;
        let x1 = Math.cos(rad) * vct[0] - Math.sin(rad) * vct[1];
        let y1 = Math.sin(rad) * vct[0] + Math.cos(rad) * vct[1];
        return [x1, y1];  // 返回的是向量
    };

    function getPntInVct([xO, yO], [xVct, yVct], k) {
        let lenVct = getVctLen([xVct, yVct]);  // 获取向量长度
        let stdVct;
        if (lenVct === 0) {
            stdVct = [0, 0];
        } else {
            stdVct = [xVct / lenVct, yVct / lenVct];   // 单位向量
        }
        return [xO + k * stdVct[0], yO + k * stdVct[1]];
    };

    var angle = 90
    setInterval(() => {
        ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height)
        let vct = [p2[0] - p1[0], p2[1] - p1[1]];  // 终点减起点,那向量的方向是起点指向终点
        let rVct = getRotateVct(vct, angle);
        let pnt = getPntInVct(p1, rVct, getVctLen(rVct))
        ctx.lineWidth = 5;

        ctx.font = "18px serif";
        ctx.beginPath();
        ctx.moveTo(p1[0], p1[1]);
        ctx.lineTo(p2[0], p2[1]);
        ctx.strokeStyle = "red";
        ctx.stroke();
        ctx.fillText("向量1", p2[0]+10, p2[1]);

        ctx.beginPath();
        ctx.moveTo(p1[0], p1[1]);
        ctx.lineTo(pnt[0], pnt[1]);
        ctx.strokeStyle = "blue";
        ctx.stroke();
        ctx.fillText("向量2", pnt[0]+10, pnt[1]);
    }, 0)


    window.addEventListener("keydown", e => {
        console.log(e.keyCode, "e.keyCode");
        if (e.keyCode === 38) {
            angle++;
        } else if (e.keyCode === 40) {
            angle--;
        }
    })

    /**
     * P 绕 O 点逆时针旋转angle角度后得到新的点坐标
     */
    // getRotatePnt = function (O, P, angle) {
    //     if (angle === 0) {
    //         return P;
    //     }
    //     let vctOP = GMarkFunc.vct(O, P),
    //         OP = GMarkFunc.getVctLen(vctOP);
    //     let dvctOQ = GMarkFunc.getRotateVct(vctOP, angle);
    //     let newPoint = GMarkFunc.getPntInVct(O, dvctOQ, OP);
    //     return newPoint;
    // };

    /**
     * P 绕 O 点逆时针旋转angle，并取一定长度len后得到新的点坐标
     */
    // GMarkFunc.getRotatePntWithLen = function (O, P, angle, len) {
    //     let vctOP = GMarkFunc.vct(O, P);
    //     let dvctOQ = GMarkFunc.getRotateVct(vctOP, angle);
    //     let Q = GMarkFunc.getPntInVct(O, dvctOQ, len);
    //     return Q;
    // };

</script>
<style>
    canvas {
        border: 1px solid #ccc;
        background-image: linear-gradient(90deg,
                #ffffb8 1%,
                rgba(0, 0, 0, 0) 5%),
            linear-gradient(#ffffb8 1%, rgba(0, 0, 0, 0) 5%);
        background-size: 28px 28px;
    }
</style>